import MFRC522 as rfid
import tone as tone
import signal
import RPi.GPIO as GPIO
from threading import Thread
from Queue import Queue
import time
import logging
import requests


authorization_server_url = "http://localhost:8280"

log = logging.getLogger('rfid-reader')
hdlr = logging.FileHandler('./logs/rfid-reader.log')
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
hdlr.setFormatter(formatter)
log.addHandler(hdlr)
log.setLevel(logging.INFO)

continue_reading = True
open_lock1=False
open_lock2=False

GPIO.setmode(GPIO.BOARD)

POWER_LED = 13
CARD_READ_LED = 11

#GPIO.setup(POWER_LED, GPIO.OUT)
GPIO.setup(CARD_READ_LED, GPIO.OUT)
#GPIO.output(POWER_LED,True)
pinNum = 18
GPIO.setup(pinNum,GPIO.OUT)

lock2 = 16
GPIO.setup(lock2,GPIO.OUT)
GPIO.output(lock2,GPIO.HIGH)

#GPIO.output(pinNum,False)

# Capture SIGINT
def end_read(signal,frame):
    global continue_reading
    print  "Ctrl+C captured, ending read."
    log.info("Ctrl+C captured, ending read.")
    continue_reading = False
    #GPIO.output(POWER_LED,False)
    #GPIO.cleanup()

signal.signal(signal.SIGINT, end_read)

rfidQueue = Queue(50)

class ProducerThread(Thread):
    def run(self):
        global rfidQueue
        global continue_reading
        while continue_reading:
            try:
                rfidValue = rfid.readRFID()
                if rfidValue != -1:
                    GPIO.output(CARD_READ_LED,True)
                    tone.playTone()
                    print "RFID=" + rfidValue
                    rfidQueue.put(rfidValue)
                    GPIO.output(CARD_READ_LED,False)
                    time.sleep(0.5)
                else:
                    time.sleep(0.005)
            except Exception, e:
                #GPIO.output(CARD_READ_LED,False)
                print str(e)
                #log.info("Error :" + str(e))


class ConsumerThread(Thread):
    def run(self):
        global rfidQueue
        #repeat = True
        global continue_reading
        while continue_reading:
            try:
                if not rfidQueue.empty():
                    rfidValue = rfidQueue.get()
                    rfidQueue.task_done()

                    #Reinitialize lock status
                    open_lock1 = False
                    open_lock2 = False

                    headers = {'cardId': rfidValue }
                    #headers = {'cardId': '179,166,242,176,87'}
                    r = requests.get(authorization_server_url+"/safe/1.0.0/lock1", headers=headers)
                    print "TagID: "+rfidValue+ " - Lock1 status=" + str(r.status_code)
                    #print "Context:" + r.text
                    if r.status_code == 200:
                        open_lock1 = True

                    r = requests.get(authorization_server_url+"/safe/1.0.0/lock2", headers=headers)
                    print "TagID: "+rfidValue+ " - Lock2 status=" + str(r.status_code)
                    #print "Context:" + r.text
                    if r.status_code == 200:
                        open_lock2 = True

                    if open_lock1 and open_lock2 :
                        print "TagID: "+rfidValue +" opened Lock1 and Lock2."
                        GPIO.output(pinNum,GPIO.LOW)
                        GPIO.output(lock2,GPIO.LOW)
                        time.sleep(0.5)
                        GPIO.output(pinNum,GPIO.HIGH)
                        GPIO.output(lock2, GPIO.HIGH)

                    elif open_lock1 :
                        print "TagID: "+rfidValue +" opened Lock1."
                        GPIO.output(pinNum,GPIO.LOW)
                        time.sleep(0.5)
                        GPIO.output(pinNum,GPIO.HIGH)

                    elif open_lock2 :
                        print "TagID: "+rfidValue +" opened Lock2."
                        GPIO.output(lock2,GPIO.LOW)
                        time.sleep(0.5)
                        GPIO.output(lock2, GPIO.HIGH)

                time.sleep(0.5)
            except Exception, e:
                log.error("Error while sending RFID to server: " + str(e))
                #repeat = True
                #time.sleep(0.5)

ProducerThread().start()
ConsumerThread().start()

try:
    while continue_reading:
        time.sleep(1)
except KeyboardInterrupt:
    GPIO.cleanup()
